<?php
/*
 *  $Id$
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * This software consists of voluntary contributions made by many individuals
 * and is licensed under the LGPL. For more information, see
 * <http://www.doctrine-project.org>.
 */

/**
 * Doctrine_Pager_Range
 *
 * @author      Guilherme Blanco <guilhermeblanco@hotmail.com>
 * @package     Doctrine
 * @subpackage  Pager
 * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
 * @version     $Revision$
 * @link        www.doctrine-project.org
 * @since       0.9
 */
abstract class Doctrine_Pager_Range
{
	/**
	 * @var array $_options     Custom Doctrine_Pager_Range implementation options
	 */
	protected $_options;

	/**
	 * @var Doctrine_Pager $pager     Doctrine_Pager object related to the pager range
	 */
	private $pager;


	/**
	 * __construct
	 *
	 * @param array $options     Custom subclass implementation options.
	 *                           Default is a blank array
	 * @param Doctrine_Pager $pager     Optional Doctrine_Pager object to be associated
	 * @return void
	 */
	final public function __construct($options = array(), $pager = null)
	{
		$this->_setOptions($options);

		if ($pager !== null) {
			$this->setPager($pager);
		}
	}

	/**
	 * getPager
	 *
	 * Returns the Doctrine_Pager object related to the pager range
	 *
	 * @return Doctrine_Pager        Doctrine_Pager object related to the pager range
	 */
	public function getPager()
	{
		return $this->pager;
	}

	/**
	 * setPager
	 *
	 * Defines the Doctrine_Pager object related to the pager range and
	 * automatically (re-)initialize Doctrine_Pager_Range
	 *
	 * @param $pager       Doctrine_Pager object related to the pager range
	 * @return void
	 */
	public function setPager($pager)
	{
		$this->pager = $pager;

		// Lazy-load initialization. It only should be called when all
		// needed information data is ready (this can only happens when we have
		// options stored and a Doctrine_Pager assocated)
		$this->_initialize();
	}

	/**
	 * getOptions
	 *
	 * Returns the custom Doctrine_Pager_Range implementation options
	 *
	 * @return array        Custom Doctrine_Pager_Range implementation options
	 */
	public function getOptions()
	{
		return $this->_options;
	}

	/**
	 * getOption
	 *
	 * Returns the custom Doctrine_Pager_Range implementation offset option
	 *
	 * @return array        Custom Doctrine_Pager_Range implementation options
	 */
	public function getOption($option)
	{
		if (isset($this->_options[$option])) {
			return $this->_options[$option];
		}

		throw new Doctrine_Pager_Exception(
            'Cannot access unexistent option \'' . $option . '\' in Doctrine_Pager_Range class'
            );
	}

	/**
	 * _setOptions
	 *
	 * Defines the subclass implementation options
	 *
	 * @param $options       Custom Doctrine_Pager_Range implementation options
	 * @return void
	 */
	protected function _setOptions($options)
	{
		$this->_options = $options;
	}

	/**
	 * isInRange
	 *
	 * Check if a given page is in the range
	 *
	 * @param $page       Page to be checked
	 * @return boolean
	 */
	public function isInRange($page)
	{
		return (array_search($page, $this->rangeAroundPage()) !== false);
	}



	/**
	 * _initialize
	 *
	 * Initialize Doctrine_Page_Range subclass which does custom class definitions
	 *
	 * @return void
	 */
	abstract protected function _initialize();


	/**
	 * rangeAroundPage
	 *
	 * Calculate and returns an array representing the range around the current page
	 *
	 * @return array
	 */
	abstract public function rangeAroundPage();
}